package com.turing.zuul.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.turing.common.response.ResponseVO;
import com.turing.common.util.JwtUtil;
import com.turing.common.util.Tools;
import com.turing.zuul.client.UserClient;
import io.jsonwebtoken.Claims;
import lombok.SneakyThrows;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;
import java.util.Set;

@Component
public class TokenFilter extends ZuulFilter {

    private Log logger = LogFactory.getLog(TokenFilter.class);

    final int order = 3;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserClient userClient;

    @Autowired
    private RedisTemplate<String,String> redisService;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return order;
    }

    @Override
    public boolean shouldFilter() {

        RequestContext ctx = RequestContext.getCurrentContext();

        String url = ctx.getRequest().getRequestURI();

        if ((!url.contains("/element/getTemplateByPage") && !url.contains("/element/getTemplate") && !url.contains("/template/queryByCondition")
            && !url.contains("/process") && !url.contains("/draw/uploadFileAndCreateTask") && !url.contains("/review/getTaskElements")
            && !url.contains("/text-alignment") && !url.contains("/text_generation"))  || url.contains("/template/getAllTemplateByName") || url.contains("/element/queryAppElementByCondition")
            || url.contains("/element/queryAllElementByCondition") || url.contains("/element/queryAllTemplateElementByConditon")
            || url.contains("/template/getTemplateById")){
            return false;
        }
        return ctx.sendZuulResponse();
    }

    @SneakyThrows
    @Override
    public Object run() {

        RequestContext ctx = RequestContext.getCurrentContext();
        String url = ctx.getRequest().getRequestURI();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getHeader("token");

        if (token == null || token.equals("")) {
            logger.info("请先登录");
            JSONObject responseJson = new JSONObject();
            responseJson.put("code", 401);
            responseJson.put("errorMessage", "请先登录");
            ctx.setResponseBody(responseJson.toJSONString());
            ctx.setResponseStatusCode(401);
            ctx.setSendZuulResponse(false);
        }

        Claims claims = null;//获取载荷

        try {
            claims = jwtUtil.parseJWT(token);
        } catch (Exception e) {
            request.setAttribute("token_fail", claims);
            logger.error("token失效,token=" + token);
            JSONObject responseJson = new JSONObject();
            responseJson.put("code", 502);
            responseJson.put("errorMessage", "token失效");
            ctx.setResponseBody(responseJson.toJSONString());
            ctx.setResponseStatusCode(502);
            ctx.setSendZuulResponse(false);
            return false;
        }

        String id = (String) claims.get("jti");
        Integer userId = Integer.valueOf(id);

        String userName = String.valueOf(claims.get("sub"));
        String tokenKey = "CLLoginUser_" + userName + "_userId_" + id;
        String userToken = redisService.opsForValue().get(tokenKey);
        if (Tools.isEmpty(userToken)) {
            logger.info("token失效" + token);
            JSONObject responseJson = new JSONObject();
            responseJson.put("code", 502);
            responseJson.put("errorMessage", "token失效");
            ctx.setResponseBody(responseJson.toJSONString());
            ctx.setResponseStatusCode(502);
            ctx.setSendZuulResponse(false);
        }

        Integer userStatus = userClient.getUserStatusById(userId);
        if (!userStatus.equals(0)) {
            logger.info("账号禁用" + token);
            JSONObject responseJson = new JSONObject();
            responseJson.put("code", 502);
            responseJson.put("errorMessage", "The account is disabled, please contact the administrator!");
            ctx.setResponseBody(responseJson.toJSONString());
            ctx.setResponseStatusCode(502);
            ctx.setSendZuulResponse(false);
            return false;
        }

        RequestContext.getCurrentContext().addZuulRequestHeader("userId", id);
        RequestContext.getCurrentContext().addZuulRequestHeader("token", URLEncoder.encode(JSON.toJSONString(claims),"UTF-8"));
        RequestContext.getCurrentContext().addZuulRequestHeader("tokenStr", token);

        return true;
    }

    public static void main(String[] args) {
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIyNTciLCJ1c2VyQ29kZSI6ImNlc2hpMDAwMSIsInN1YiI6Iua1i-ivleS4k-eUqO-8iOWLv-WIoO-8iSIsImlhdCI6MTY1NjU1NjA5NCwibWFpblJvbGVJZCI6MjY2LCJtYWluUm9sZU5hbWUiOiLmnYPpmZDmtYvor5XvvIjli7_liKDvvIkiLCJyb2xlcyI6IlsyNjYsIDI2N10iLCJyb2xlTmFtZXMiOiJb5p2D6ZmQ5rWL6K-V77yI5Yu_5Yig77yJLCDmtYvor5XkuJPnlKgwMl0iLCJtZW51TGlzdCI6WzEsMiw1LDcsOCw5LDEwLDExLDEyLDEzXSwidGVtcGxhdGVzIjp7IjEwIjowfSwiZWxlbWVudHMiOnt9LCJjb21wYXJlVGVtcGxhdGVzIjpbXSwiZGF0YVByaXZpbGVnZSI6InJvbGUiLCJleHAiOjE2NTcxNjA4OTR9.FfGTar79xcSxSNIXNHTeSC76C6-VLtL-up89jW_le_g";
        Claims claims = null;//获取载荷

        try {
            JwtUtil jwtUtil = new JwtUtil();
            claims = jwtUtil.parseJWT(token);
        } catch (Exception e) {

        }
    }

}